package com.zl.tby.screen.service.impl;

import com.zl.tby.core.base.util.ToolsUtil;
import com.zl.tby.dto.TbyCarRecordQuery;
import com.zl.tby.dto.TbyFaceRecordQuery;
import com.zl.tby.screen.service.ITbyCarMonitorScreenService;
import com.zl.tby.screen.vo.carMonitor.TbyCarMonitorBean;
import org.noear.solon.annotation.Component;
import org.noear.wood.DbContext;
import org.noear.wood.annotation.Db;
import org.noear.wood.utils.StringUtils;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 大屏 车辆监控接口实现
 * @author changpeng
 * @version 1.0
 * @since 2024/9/19 12:57
 */
@Component
public class TbyCarMonitorScreenServiceImpl implements ITbyCarMonitorScreenService {

    @Db
    private DbContext db;

    @Override
    public List<TbyCarMonitorBean> kkStatistic(TbyCarRecordQuery query) {
        try {
            List<TbyCarMonitorBean> dbList = db.table("tby_car_record").whereTrue()
                    .andIf(StringUtils.isNotEmpty(query.getStartDate()), "cap_date >= ?", query.getStartDate() + " 00:00:00")
                    .andIf(StringUtils.isNotEmpty(query.getEndDate()), "cap_date <= ?", query.getEndDate() + " 23:59:59")
                    .groupBy("device_code")
                    .orderBy("count(id) desc")
                    .selectList("count(id) data_count, device_code, device_name", TbyCarMonitorBean.class);
            return dbList;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return new ArrayList<>();
    }

    @Override
    public List<TbyCarMonitorBean> carNumber(TbyCarRecordQuery query) {
        try {
            if (StringUtils.isEmpty(query.getStartDate()) || StringUtils.isEmpty(query.getEndDate())) {
                return new ArrayList<>();
            }
            String startMonth = ToolsUtil.dateUtil2String(ToolsUtil.dateString2Util(query.getStartDate(), "yyyy-MM-dd"), "yyyy-MM");
            String endMonth = ToolsUtil.dateUtil2String(ToolsUtil.dateString2Util(query.getEndDate(), "yyyy-MM-dd"), "yyyy-MM");
            if (startMonth.equals(endMonth)) {
                // 相同月份的情况
                return sameMonth(query);
            } else {
                // 判断是否是同一年
                String startYear = ToolsUtil.dateUtil2String(ToolsUtil.dateString2Util(query.getStartDate(), "yyyy-MM-dd"), "yyyy");
                String endYear = ToolsUtil.dateUtil2String(ToolsUtil.dateString2Util(query.getEndDate(), "yyyy-MM-dd"), "yyyy");
                return noSameMonth(query, startYear.equals(endYear));
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    /**
     * 相同月份的情况
     * @param query: 查询条件
     * @return 结果
     */
    private List<TbyCarMonitorBean> sameMonth(TbyCarRecordQuery query) throws Exception {
        // 相同月份，按照每天查询
        List<LocalDate> dataList = ToolsUtil.getDatesBetween(LocalDate.parse(query.getStartDate(), DateTimeFormatter.ISO_LOCAL_DATE),
                LocalDate.parse(query.getEndDate(), DateTimeFormatter.ISO_LOCAL_DATE));
        List<TbyCarMonitorBean> dbList = db.table("tby_car_record").whereTrue()
                .andIf(StringUtils.isNotEmpty(query.getStartDate()), "cap_date >= ?", query.getStartDate() + " 00:00:00")
                .andIf(StringUtils.isNotEmpty(query.getEndDate()), "cap_date <= ?", query.getEndDate() + " 23:59:59")
                .groupBy("left(cap_date, 10)")
                .orderBy("cap_date")
                .selectList("count(id) data_count, left(cap_date, 10) date", TbyCarMonitorBean.class);
        Map<String, TbyCarMonitorBean> map = new HashMap<>(0);
        for (TbyCarMonitorBean data : dbList) {
            map.put(data.getDate(), data);
        }
        List<TbyCarMonitorBean> entityList = new ArrayList<>();
        for (LocalDate localDate : dataList) {
            String date = localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            String day = localDate.format(DateTimeFormatter.ofPattern("dd"));
            if (map.containsKey(date)) {
                TbyCarMonitorBean entity = map.get(date);
                entity.setRealDate(date);
                entity.setDate(Integer.parseInt(day) + "日");
                entityList.add(entity);
            } else {
                TbyCarMonitorBean entity = new TbyCarMonitorBean();
                entity.setRealDate(date);
                entity.setDate(Integer.parseInt(day) + "日");
                entity.setDataCount(0L);
                entityList.add(entity);
            }
        }
        return entityList;
    }

    private List<TbyCarMonitorBean> noSameMonth(TbyCarRecordQuery query, boolean saveYear) throws Exception {
        // 相同年份，按照每天查询
        List<LocalDate> dataList = ToolsUtil.getMonthBetween(LocalDate.parse(query.getStartDate(), DateTimeFormatter.ISO_LOCAL_DATE),
                LocalDate.parse(query.getEndDate(), DateTimeFormatter.ISO_LOCAL_DATE));
        List<TbyCarMonitorBean> dbList = db.table("tby_car_record").whereTrue()
                .andIf(StringUtils.isNotEmpty(query.getStartDate()), "cap_date >= ?", query.getStartDate() + " 00:00:00")
                .andIf(StringUtils.isNotEmpty(query.getEndDate()), "cap_date <= ?", query.getEndDate() + " 23:59:59")
                .groupBy("left(cap_date, 7)")
                .orderBy("cap_date")
                .selectList("count(id) data_count, left(cap_date, 7) date", TbyCarMonitorBean.class);
        Map<String, TbyCarMonitorBean> map = new HashMap<>(0);
        for (TbyCarMonitorBean data : dbList) {
            map.put(data.getDate(), data);
        }
        List<TbyCarMonitorBean> entityList = new ArrayList<>();
        for (LocalDate localDate : dataList) {
            String date = localDate.format(DateTimeFormatter.ofPattern("yyyy-MM"));
            String day = localDate.format(DateTimeFormatter.ofPattern("MM"));
            if (map.containsKey(date)) {
                TbyCarMonitorBean entity = map.get(date);
                entity.setRealDate(date);
                if (saveYear) {
                    entity.setDate(Integer.parseInt(day) + "月");
                }
                entityList.add(entity);
            } else {
                TbyCarMonitorBean entity = new TbyCarMonitorBean();
                entity.setRealDate(date);
                if (saveYear) {
                    entity.setDate(Integer.parseInt(day) + "月");
                } else {
                    entity.setDate(date);
                }
                entity.setDataCount(0L);
                entityList.add(entity);
            }
        }
        return entityList;
    }

    @Override
    public List<TbyCarMonitorBean> faceNumber(TbyFaceRecordQuery query) {
        try {
            if (StringUtils.isEmpty(query.getStartDate()) || StringUtils.isEmpty(query.getEndDate())) {
                return new ArrayList<>();
            }
            String startMonth = ToolsUtil.dateUtil2String(ToolsUtil.dateString2Util(query.getStartDate(), "yyyy-MM-dd"), "yyyy-MM");
            String endMonth = ToolsUtil.dateUtil2String(ToolsUtil.dateString2Util(query.getEndDate(), "yyyy-MM-dd"), "yyyy-MM");
            if (startMonth.equals(endMonth)) {
                // 相同月份的情况
                return sameMonthFace(query);
            } else {
                // 判断是否是同一年
                String startYear = ToolsUtil.dateUtil2String(ToolsUtil.dateString2Util(query.getStartDate(), "yyyy-MM-dd"), "yyyy");
                String endYear = ToolsUtil.dateUtil2String(ToolsUtil.dateString2Util(query.getEndDate(), "yyyy-MM-dd"), "yyyy");
                return noSameMonthFace(query, startYear.equals(endYear));
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    /**
     * 相同月份的情况
     * @param query: 查询条件
     * @return 结果
     */
    private List<TbyCarMonitorBean> sameMonthFace(TbyFaceRecordQuery query) throws Exception {
        // 相同月份，按照每天查询
        List<LocalDate> dataList = ToolsUtil.getDatesBetween(LocalDate.parse(query.getStartDate(), DateTimeFormatter.ISO_LOCAL_DATE),
                LocalDate.parse(query.getEndDate(), DateTimeFormatter.ISO_LOCAL_DATE));
        List<TbyCarMonitorBean> dbList = db.table("tby_face_record").whereTrue()
                .andIf(StringUtils.isNotEmpty(query.getStartDate()), "grab_time >= ?", query.getStartDate() + " 00:00:00")
                .andIf(StringUtils.isNotEmpty(query.getEndDate()), "grab_time <= ?", query.getEndDate() + " 23:59:59")
                .groupBy("left(grab_time, 10)")
                .orderBy("grab_time")
                .selectList("count(id) data_count, left(grab_time, 10) date", TbyCarMonitorBean.class);
        Map<String, TbyCarMonitorBean> map = new HashMap<>(0);
        for (TbyCarMonitorBean data : dbList) {
            map.put(data.getDate(), data);
        }
        List<TbyCarMonitorBean> entityList = new ArrayList<>();
        for (LocalDate localDate : dataList) {
            String date = localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            String day = localDate.format(DateTimeFormatter.ofPattern("dd"));
            if (map.containsKey(date)) {
                TbyCarMonitorBean entity = map.get(date);
                entity.setRealDate(date);
                entity.setDate(Integer.parseInt(day) + "日");
                entityList.add(entity);
            } else {
                TbyCarMonitorBean entity = new TbyCarMonitorBean();
                entity.setRealDate(date);
                entity.setDate(Integer.parseInt(day) + "日");
                entity.setDataCount(0L);
                entityList.add(entity);
            }
        }
        return entityList;
    }

    private List<TbyCarMonitorBean> noSameMonthFace(TbyFaceRecordQuery query, boolean saveYear) throws Exception {
        // 相同年份，按照每天查询
        List<LocalDate> dataList = ToolsUtil.getMonthBetween(LocalDate.parse(query.getStartDate(), DateTimeFormatter.ISO_LOCAL_DATE),
                LocalDate.parse(query.getEndDate(), DateTimeFormatter.ISO_LOCAL_DATE));
        List<TbyCarMonitorBean> dbList = db.table("tby_face_record").whereTrue()
                .andIf(StringUtils.isNotEmpty(query.getStartDate()), "grab_time >= ?", query.getStartDate() + " 00:00:00")
                .andIf(StringUtils.isNotEmpty(query.getEndDate()), "grab_time <= ?", query.getEndDate() + " 23:59:59")
                .groupBy("left(grab_time, 7)")
                .orderBy("grab_time")
                .selectList("count(id) data_count, left(grab_time, 7) date", TbyCarMonitorBean.class);
        Map<String, TbyCarMonitorBean> map = new HashMap<>(0);
        for (TbyCarMonitorBean data : dbList) {
            map.put(data.getDate(), data);
        }
        List<TbyCarMonitorBean> entityList = new ArrayList<>();
        for (LocalDate localDate : dataList) {
            String date = localDate.format(DateTimeFormatter.ofPattern("yyyy-MM"));
            String day = localDate.format(DateTimeFormatter.ofPattern("MM"));
            if (map.containsKey(date)) {
                TbyCarMonitorBean entity = map.get(date);
                entity.setRealDate(date);
                if (saveYear) {
                    entity.setDate(Integer.parseInt(day) + "月");
                }
                entityList.add(entity);
            } else {
                TbyCarMonitorBean entity = new TbyCarMonitorBean();
                entity.setRealDate(date);
                if (saveYear) {
                    entity.setDate(Integer.parseInt(day) + "月");
                } else {
                    entity.setDate(date);
                }
                entity.setDataCount(0L);
                entityList.add(entity);
            }
        }
        return entityList;
    }

    @Override
    public List<TbyCarMonitorBean> faceStatistic(TbyFaceRecordQuery query) {
        try {
            List<TbyCarMonitorBean> dbList = db.table("tby_face_record").whereTrue()
                    .andIf(StringUtils.isNotEmpty(query.getStartDate()), "grab_time >= ?", query.getStartDate() + " 00:00:00")
                    .andIf(StringUtils.isNotEmpty(query.getEndDate()), "grab_time <= ?", query.getEndDate() + " 23:59:59")
                    .groupBy("dev_id, dev_name")
                    .orderBy("count(id) desc")
                    .selectList("count(id) data_count, dev_id as device_code, dev_name as device_name", TbyCarMonitorBean.class);
            return dbList;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return new ArrayList<>();
    }
}
